﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Linq;
//
using CookComputing.XmlRpc;
using PerceptiveMCAPI.Types.Internal;
//
namespace PerceptiveMCAPI.Types
{
	public class campaignEmailStatsAIMAllOutput : Api_BaseOutput
	{
		public campaignEmailStatsAIMAllResults result { get; set; }
		public campaignEmailStatsAIMAllParms inputParms { get; private set; }
		// --------------------------------------------------------
		public campaignEmailStatsAIMAllOutput( campaignEmailStatsAIMAllInput input )
			: base( input )
		{
			inputParms = input.parms;
			result = new campaignEmailStatsAIMAllResults();
		}
		// --------------------------------------------------- tostring
		public override string ToString()
		{
			return string.Format( "AIM Stats: {0}", this.result.data.Count );
		}

		#region ================================================================== format setup

		// ---- serial
		internal void Format( string api_Request, string api_Response )
		{
			this.api_Request = api_Request;
			this.api_Response = api_Response;
			// ----------------------------------
			if ( this.api_OutputType == EnumValues.OutputType.JSON )
				outputJSON();
			else if ( this.api_OutputType == EnumValues.OutputType.XML )
				outputXML();
		}

		// ---- xmlrpc
		internal void Format( x_campaignEmailStatsAIMAll rpcResult )
		{
			this.api_Request = EnumValues.NotSupplied;
			this.api_Response = EnumValues.NotSupplied;
			// ------------------------
			this.result = FormatStats( rpcResult );
		}

		#endregion

		#region ================================================================= Output

		// ---------------------------------------------------------- outputXML
		private void outputXML()
		{
			XElement xml = XElement.Parse( this.api_Response );
			// error check
			Api_Error error = apiSerial.GetXmlOutputError( xml );
			if ( error != null )
			{
				this.api_ErrorMessages.Add( error );
				return;
			}
			// -------------------------------------------- get values
			DateTime dt; int it;
			try
			{
				int.TryParse( xml.Element( "total" ).Value, out it );
				result.total = it;
				//
				IEnumerable<XElement> all = xml.Element( "data" ).Elements( "struct" );
				foreach ( XElement entry in all )
				{
					campaignEmailStatsAIMResults.EmailActivity item = new campaignEmailStatsAIMResults.EmailActivity();
					item.email_address = entry.Attribute( "key" ).Value;
					if ( entry.HasElements )
					{
						IEnumerable<XElement> emailResults = entry.Elements( "struct" );
						foreach ( XElement activity in emailResults )
						{
							campaignEmailStatsAIMResults.EmailActivity.Activity emact =
								new campaignEmailStatsAIMResults.EmailActivity.Activity();
							emact.action = activity.Element( "action" ).Value;
							DateTime.TryParse( activity.Element( "timestamp" ).Value, out dt );
							emact.timestamp = dt;
							emact.url = activity.Element( "url" ).Value;
							emact.ip = activity.Element( "ip" ).Value;
							item.activity.Add( emact );
						}
					}
					this.result.data.Add( item );
				}
			}
			catch ( Exception ex )
			{
				this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}

		// ---------------------------------------------------------- outputJSON
		private void outputJSON()
		{
			JavaScriptSerializer jss = new JavaScriptSerializer();

			try
			{
				if ( this.api_Response.Contains( EnumValues.JSONErrorString ) )
				{
					Api_Error err = jss.Deserialize<Api_Error>( this.api_Response );
					this.api_ErrorMessages.Add( err );
				}
				else
				{
					if ( this.api_Response.GetType().IsArray ) return;

					x_campaignEmailStatsAIMAll jsonResult = jss.Deserialize<x_campaignEmailStatsAIMAll>( this.api_Response );
					this.result = FormatStats( jsonResult );
				}
			}
			catch ( Exception ex )
			{
				this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}

		// ---------------------------------------------------------- Formatting
		private campaignEmailStatsAIMAllResults FormatStats( x_campaignEmailStatsAIMAll x_results )
		{
			DateTime dt;
			campaignEmailStatsAIMAllResults results = new campaignEmailStatsAIMAllResults();

			results.total = x_results.total;
			IDictionary x_data = x_results.data as IDictionary;
			//
			IDictionaryEnumerator de = x_data.GetEnumerator();
			while ( de.MoveNext() )
			{
				var email_activity = new campaignEmailStatsAIMResults.EmailActivity();
				email_activity.email_address = de.Key.ToString();
				//
				var actions = de.Value as object[];
				if ( actions.Length > 0 )
				{
					foreach ( var act in actions )
					{
						campaignEmailStatsAIMResults.EmailActivity.Activity activity =
							new campaignEmailStatsAIMResults.EmailActivity.Activity();
						var action = act as IDictionary;
						activity.action = action["action"].ToString();
						if ( action["url"] != null )
							activity.url = action["url"].ToString();
						DateTime.TryParse( action["timestamp"].ToString(), out dt );
						activity.timestamp = dt;
						activity.ip = action["ip"].ToString();
						//
						email_activity.activity.Add( activity );
					}
				}
				//
				results.data.Add( email_activity );
			}
			return results;
		}

		#endregion
	}
}
